﻿#region licence
//  Copyright 2008 Michael Cromwell

//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at

//       http://www.apache.org/licenses/LICENSE-2.0

//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Boo.Lang;

namespace log4net.altconf
{
    /// <summary>
    /// Used to wrap up calls made to an <see cref="IAppender"/> object
    /// so that properties and method calls can be forwarded via reflection
    /// </summary>
    public class AppenderQuackFuAdapter : IQuackFu
    {
        protected object appender;
        protected Type appenderType;
        public AppenderQuackFuAdapter(object appender)
        {
            this.appender = appender;
            appenderType = this.appender.GetType();
        }

        public object QuackGet(string name, object[] parameters)
        {
            var prop = appenderType.GetProperty(name);
            if (prop != null)
                return prop.GetValue(appender, null);
            else
                throw new InvalidOperationException(string.Format("appender does not have property: '{0}'", name));
        }

        public object QuackInvoke(string name, params object[] args)
        {
            var mth = appenderType.GetMethod(name);
            if (mth != null)
            {
                var parameters = mth.GetParameters();
                if (args.Count() != parameters.Count())
                    throw new InvalidOperationException(string.Format("method '{0}' must be supplied with '{1}' number of arguments.", name, parameters.Count()));

                mth.Invoke(appender, args);
            }
            else
            {
                throw new InvalidOperationException(string.Format("appender does not have method: '{0}'", name));
            }

            return null;
        }

        public object QuackSet(string name, object[] parameters, object value)
        {
            var prop = appenderType.GetProperty(name);
            if (prop != null)
                prop.SetValue(appender, value, null);
            else
                throw new InvalidOperationException(string.Format("appender does not have property: '{0}'", name));

            return null;
        }
                
    }
}
